Hive 获取数组最后一个元素

28 篇文章 1 订阅
18 篇文章 2 订阅

引言:

通过split分割当前字段获取数组,并得到最后一个索引的元素,通过hive怎么实现,下面通过不同方法一一验证可行性。

字段样式 shopList  : productA,productB,productC 

表名 shopTable :  shopListTable

一.split + size 获取 - 失败

 hive -e "
 select split(shopList,',')[size(split(shopList,','))-1]
 from shopTable;
 "
FAILED: SemanticException 2:25 Non-constant expressions for array indexes not supported. Error encountered near token '1'

遇到这个问题第一反应就是split转化为数组,再通过数组size-1获取最后一位,但是 array 的索引位置不允许非常数的表达式,所以失败。

二.split + size + cast 获取 - 失败

hive -e "
select array[index] as product
from
( select split(shopList,',') array, cast((size(split(shopList,',')) - 1) as int) index from shopTable) tmp
";
FAILED: SemanticException 2:12 Non-constant expressions for array indexes not supported. Error encountered near token 'index'

和上面的问题类似,有点坑,继续尝试。

三. regexp_extract - 能跑但效果不对

hive -e "
select regexp_extract(shopList,'(\,[^\,]+)',1) 
from shopTable
";

split 和 regexp_extract 作用类似,但是这里正则表达式使用起来有问题,还是暂不考虑。

四. reverse + split + reverse - 成功

hive -e "
select reverse(split(reverse(shopList), ',')[1]) 
from shopTable";

看网上大神这么操作的,实测没有问题,但是性能和资源消耗都比较严重。

五.自定义UDF - 成功 (推荐👍)

截止目前上面四种方法只有 reverse 一种可以实现但是效率还是个问题,所以出大招直接自己写函数好了。

java : 

package com.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import java.util.List;

/**
 * @title: SplitString
 * @Date: 2021-01-21 14:21
 * @Version 1.0
 */
public final class SplitString extends UDF {
    public Text evaluate(final Text s) {
        if (s == null) { return null; }
        String[] arr = s.toString().split(",");
        if ( arr.length == 0) { return null; }
        return new Text(arr[arr.length - 1]);
    }
}

sh :

hive -e "
add jar ~/your-class-1.0-SNAPSHOT.jar;
create temporary function my_split as 'com.hive.udf.SplitString';
select my_split(shopList) from shopTable group by my_split(shopList);
"

将java代码打包,并上传至sh脚本对应位置即可,通过自定义的方法实现 split + index 功能,这里不局限于倒数第一位,倒数第几位都可以,实测性能优于 reverse, 值得拥有!

除了UDF(一进一出)之外,还有 UDAF (多进一出)和 UDTF(一进多出)等形式,有兴趣也可以自己实现~

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIT_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值